package com.cellngine.client;

import static org.lwjgl.opengl.GL11.*;

import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.WindowEvent;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextField;
import javax.swing.WindowConstants;

import org.lwjgl.LWJGLException;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.Display;

/**
 * Cellngine graphics engine using LWJGL
 * 
 * @author James Wood <Chryseus8086@gmail.com>
 */
public class Engine
{
	
	private int			displayWidth;
	private int			displayHeight;
	private JFrame		mainWindow;
	private JPanel		mainPanel;
	private JPanel		sidePanel;
	private Canvas		renderTarget;
	private JTextField	inputBox;
	private JButton		sendButton;
	
	public Engine()
	{
		
		//setupDisplay(1024, 768, 32, false);
		setupDisplayCanvas();
		setupDefaultProjection();
		mainLoop();
	}
	
	public void setupDisplayCanvas()
	{
		final GridBagConstraints c = new GridBagConstraints();
		mainWindow = new JFrame("Cellngine Test");
		mainPanel = new JPanel(new GridBagLayout());
		sidePanel = new JPanel(new GridBagLayout());
		renderTarget = new Canvas();
		inputBox = new JTextField();
		sendButton = new JButton("Send..");
		
		sidePanel.setMinimumSize(new Dimension(200, 0));
		
		c.fill = GridBagConstraints.BOTH;
		c.weightx = 0.5;
		c.weighty = 0.5;
		c.anchor = GridBagConstraints.NORTHWEST;
		c.gridx = 0;
		c.gridy = 0;
		c.gridwidth = 2;
		mainPanel.add(renderTarget, c);
		
		c.gridwidth = 1;
		c.anchor = GridBagConstraints.SOUTHWEST;
		c.weightx = 1;
		c.weighty = 0;
		c.fill = GridBagConstraints.HORIZONTAL;
		c.gridy = 1;
		mainPanel.add(inputBox, c);
		
		c.gridx = 1;
		c.anchor = GridBagConstraints.SOUTHEAST;
		c.fill = GridBagConstraints.NONE;
		c.weightx = 0;
		mainPanel.add(sendButton, c);
		
		c.gridx = 2;
		c.gridy = 0;
		c.anchor = GridBagConstraints.EAST;
		c.weightx = 0.2;
		c.weighty = 1;
		c.gridheight = 2;
		mainPanel.add(sidePanel, c);
		
		mainWindow.add(mainPanel);
		mainWindow.setVisible(true);
		mainWindow.setSize(1024, 768);
		mainWindow.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
		try
		{
			Display.setParent(renderTarget);
			Display.create();
		}
		catch (final LWJGLException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		displayWidth = renderTarget.getWidth();
		displayHeight = renderTarget.getHeight();
		renderTarget.setFocusable(true);
		renderTarget.requestFocus();
		renderTarget.setIgnoreRepaint(true);
	}
	
	/**
	 * Toggles between fullscreen and windowed mode.
	 */
	public void toggleFullscreen()
	{
		final boolean full = Display.isFullscreen();
		try
		{
			Display.setFullscreen(!full);
		}
		catch (final LWJGLException e)
		{
			e.printStackTrace();
		}
	}
	
	/**
	 * The default projection matrix setup, 1:1 2D projection.
	 */
	public void setupDefaultProjection()
	{
		glLoadIdentity();
		glViewport(0, 0, displayWidth, displayHeight);
		glMatrixMode(GL_PROJECTION);
		glLoadIdentity();
		glOrtho(0.0, displayWidth, 0.0, displayHeight, -1, 1);
		glMatrixMode(GL_MODELVIEW);
		glEnable(GL_TEXTURE_2D);
		glEnable(GL_BLEND);
		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
		
		//glTranslatef(0f, 0f, 0.0f);
		//glLoadIdentity();
		glScalef(1.0f, -1.0f, 1.0f);
		glTranslatef(0f, -displayHeight, 0.0f);
	}
	
	/**
	 * The main rendering method.
	 */
	public void mainLoop()
	{
		
		final TextureManager TM = new TextureManager(); // The new all-in-one texture manager
		TM.loadTexture("data/floor_grille.png", "floor_grille", FileFormat.FORMAT_PNG); // Loading a texture
		TM.loadTexture("data/test_tile.png", "test_tile", FileFormat.FORMAT_PNG); // and another
		TM.loadTexture("data/space.png", "space", FileFormat.FORMAT_PNG);
		TM.loadTexture("data/grid.png", "grid", FileFormat.FORMAT_PNG);
		
		final Map map = new Map(TM);
		map.generate();
		
		while (!Keyboard.isKeyDown(Keyboard.KEY_ESCAPE))
		{
			
			if (Keyboard.isKeyDown(Keyboard.KEY_F))
			{
				toggleFullscreen();
			}
			
			if (Keyboard.isKeyDown(Keyboard.KEY_G))
			{
				try
				{
					Thread.sleep(200);
					map.toggleGrid();
				}
				catch (final InterruptedException e)
				{
					e.printStackTrace();
				}
			}
			
			if (displayWidth != renderTarget.getWidth()
					|| displayHeight != renderTarget.getHeight())
			{
				displayWidth = renderTarget.getWidth();
				displayHeight = renderTarget.getHeight();
				setupDefaultProjection();
			}
			
			glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
			
			map.draw();
			
			Display.sync(60);
			Display.update();
		}
		mainWindow.setVisible(false);
		final WindowEvent wev = new WindowEvent(mainWindow, WindowEvent.WINDOW_CLOSING);
		Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(wev);
		System.exit(0);
	}
}
